﻿using System;
using System.Collections.Generic;
using System.Linq;
using Eg.Core;
using NHibernate;
using NHibernate.Linq;

namespace Linq2NH
{

    public class Queries
    {

        private readonly ISession _session;

        public Queries(ISession session)
        {
            if (session == null)
                throw new ArgumentNullException("session");
            _session = session;
        }

        public IEnumerable<Movie> GetMoviesDirectedBy(string directorName)
        {
            var query = from m in _session.Query<Movie>()
                        where m.Director == directorName
                        select m;
            return query.ToList();
        }

        public IEnumerable<Movie> GetMoviesWith(string actorName)
        {
            var query = from m in _session.Query<Movie>()
                        where m.Actors.Any(
                        ar => ar.Actor == actorName)
                        select m;
            return query.ToList();
        }

        public Book GetBookByISBN(string isbn)
        {
            var query = from b in _session.Query<Book>()
                        where b.ISBN == isbn
                        select b;
            return query.SingleOrDefault();
        }

        public IEnumerable<Product> GetProductByPrice(decimal minPrice, decimal maxPrice)
        {
            var query = from p in _session.Query<Product>()
                        where p.UnitPrice >= minPrice && p.UnitPrice <= maxPrice
                        orderby p.UnitPrice ascending
                        select p;
            return query.ToList();
        }

        public IEnumerable<NameAndPrice> GetMoviePriceList()
        {
            var query = from m in _session.Query<Movie>()
                        select new NameAndPrice(m.Name, m.UnitPrice);
            return query.ToList();
        }

        public decimal GetAverageMoviePrice()
        {
            return _session.Query<Movie>()
            .Average(m => m.UnitPrice);
        }


        public IEnumerable<NameAndPrice> GetAvgDirectorPrice()
        {
            var query = from m in _session.Query<Movie>()
                        group m by m.Director
                            into g
                            select new NameAndPrice(g.Key, g.Average(i => i.UnitPrice));
            return query.ToList();
        }

    }

}
